#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>

#include "picture.h"
#include "ak_mem.h"
#include "ak_log.h"

int layer_init()
{
    /* start the application */
    sdk_run_config config;
    memset(&config, 0, sizeof(sdk_run_config));
    config.mem_trace_flag = SDK_RUN_NORMAL;
    ak_sdk_init( &config );//???

    int ret = 0;
    /* fill the struct to open the vo */
    struct ak_vo_param    param;
    //设置打开屏幕的参数
    /* fill the struct ready to open */
    param.width = 1024;
    param.height = 600;
    param.format = GP_FORMAT_BGR888;  //format to output
    param.rotate = AK_GP_ROTATE_NONE;    //rota te value
    param.init_mode = AK_VO_INIT_WHIHE;

    ret = ak_vo_open(&param, DEV_NUM);      //open vo
    if(ret != 0) 
    {
        /* open failed return -1 */
        printf("ak_vo_open failed![%d]\n",ret);
        return AK_FAILED;
    }

    //创建bg图层(找多大的画布给你画)
    /* create the video layer */
    struct ak_vo_layer_in layer_in_param;
    struct ak_vo_layer_out ret_bg_info;
    struct ak_vo_layer_out ret_gui_info;
    layer_in_param.create_layer.width  = 1024;    //1280; //get the res
    layer_in_param.create_layer.height = 600;   //800; //get the res
    /* just from (0,0) */
    layer_in_param.create_layer.left  = 0;         //layer left pos
    layer_in_param.create_layer.top   = 0;         // layer top pos
    layer_in_param.layer_opt          = GP_OPT_NONE;
    layer_in_param.format             = GP_FORMAT_BGR888;
     /* vo layer create api */
    ret = ak_vo_create_bg_layer(&layer_in_param, AK_VO_LAYER_BG_1, &ret_bg_info);
    if(ret != 0) {
        /* if failed, close the vo */
        printf("ak_vo_create_bg_layer failed![%d]\n",ret);
        ak_vo_close(DEV_NUM);       // if failed, close the vo
        return AK_FAILED;
    }

    printf("create bg_layer success!\n");

    /* use the double buff mode */
    ret = ak_vo_set_fbuffer_mode(AK_VO_BUFF_DOUBLE);
    if(ret != 0) {
        /* if failed, close the vo */
        printf("ak_vo_set_fbuffer_mode failed![%d]\n",ret);
        ak_vo_close(DEV_NUM);       // if failed, close the vo
        return AK_FAILED;
    }

    return AK_SUCCESS;
}

int load_rgb_file(const char *path, struct rgb_info *rgb_data)
{
    FILE *fp = fopen(path, "rb");
    if(fp == NULL) 
    {
        printf("open %s fail", path);
        ak_vo_close(DEV_NUM);
        return AK_FAILED;
    }
    
    int len = rgb_data->width*rgb_data->height*3;
    int ret = 0;

    /* need dma mem */
    rgb_data->rgb_buffer = ak_mem_dma_alloc(MODULE_ID_APP, len);
    if(rgb_data->rgb_buffer == NULL) 
    {
        printf("Can't malloc DMA memory!\n");
        ak_vo_close(DEV_NUM);
        fclose(fp);
        return AK_FAILED;
    }

    memset(rgb_data->rgb_buffer, 0, len);
    if ( ( ret = fread(rgb_data->rgb_buffer, 1, len, fp) ) > 0 ) 
    {     // read the file
        // printf("read [%d] byte to dma buffer\n",ret);
        //fclose(fp); test!!!
    }
    else
    {
        printf("read fail[%d]\n", ret);
        ak_vo_close(DEV_NUM);
        fclose(fp);
        return AK_FAILED;
    }
    
    return AK_SUCCESS;
}


int load_rgba_file(const char *path, struct rgba_info *rgba_data)
{
    FILE *fp = fopen(path, "rb");
    if(fp == NULL) 
    {
        printf("open %s fail", path);
        ak_vo_close(DEV_NUM);
        return AK_FAILED;
    }
    
    int len = rgba_data->width*rgba_data->height*4;
    int ret = 0;

    /* need dma mem */
    rgba_data->rgba_buffer = ak_mem_dma_alloc(MODULE_ID_APP, len);
    if(rgba_data->rgba_buffer == NULL) 
    {
        printf("Can't malloc DMA memory!\n");
        ak_vo_close(DEV_NUM);
        fclose(fp);
        return AK_FAILED;
    }

    memset(rgba_data->rgba_buffer, 0, len);
    if ( ( ret = fread(rgba_data->rgba_buffer, 1, len, fp) ) > 0 ) 
    {     // read the file
        // printf("read [%d] byte to dma buffer\n",ret);
    }
    else
    {
        printf("read fail[%d]\n", ret);
        ak_vo_close(DEV_NUM);
        fclose(fp);
        return AK_FAILED;
    }
    
    return AK_SUCCESS;
}

int free_rgb_mem(struct rgb_info *rgb_data)
{
    if(ak_mem_dma_free(rgb_data->rgb_buffer) != 0)
    {
        printf("free mem fail!\n");
        return -1;
    }
    return 0;
}

int free_rgba_mem(struct rgba_info *rgba_data)
{
    if(ak_mem_dma_free(rgba_data->rgba_buffer) != 0)
    {
        printf("free mem fail!\n");
        return -1;
    }
    return 0;
}

int output_picture(struct rgb_info *rgb_data)
{
    //制作图像对象
    /* obj add */
    struct ak_vo_obj obj;

    //取图像的方式
    /* set obj src info*/
    obj.format = GP_FORMAT_BGR888;
    obj.cmd = GP_OPT_SCALE;
    obj.vo_layer.width = rgb_data->width;
    obj.vo_layer.height = rgb_data->height;
    obj.vo_layer.clip_pos.top = 0;
    obj.vo_layer.clip_pos.left = 0;
    obj.vo_layer.clip_pos.width = rgb_data->width;
    obj.vo_layer.clip_pos.height = rgb_data->height;

    ak_mem_dma_vaddr2paddr(rgb_data->rgb_buffer, &(obj.vo_layer.dma_addr));

        /* set dst_layer 1 info*/
    obj.dst_layer.top = 0;
    obj.dst_layer.left = 0;
    obj.dst_layer.width = rgb_data->width;
    obj.dst_layer.height = rgb_data->height;
    /* display obj 1*/
    if(ak_vo_add_obj(&obj, AK_VO_LAYER_BG_1)<0)
    {
        printf("add obj fail\n");
        return AK_FAILED;
    }
    /* refresh screen */
    if(ak_vo_refresh_screen(0x1<<AK_VO_LAYER_BG_1) < 0)
    {
        printf("refresh bg fail!\n");
        return AK_FAILED;
    } 
    return AK_SUCCESS;
}

// int get_picture_data(PictureOBJ* _pic_obj)
// {
//     FILE *fp = fopen(_pic_obj->srcPath, "rb");
//     if(fp == NULL) 
//     {
//         printf("open %s fail", _pic_obj->srcPath);
//         ak_vo_close(DEV_NUM);
//         return AK_FAILED;
//     }
    
//     int len, ret;
//     if(_pic_obj->Format == GP_FORMAT_RGBA8888)
//     {len = _pic_obj->srcSize.height * _pic_obj->srcSize.width * 4;}
//     else if(_pic_obj->Format == GP_FORMAT_RGB888)
//     {len = _pic_obj->srcSize.height * _pic_obj->srcSize.width*3;}
//     else
//     {
//         printf("Format error! %d", _pic_obj->Format);
//         ak_vo_close(DEV_NUM);
//         fclose(fp);
//         return -1;
//     }

//     /* need dma mem */
//     _pic_obj->contentBuffer = ak_mem_dma_alloc(MODULE_ID_APP, len);
//     if(_pic_obj->contentBuffer == NULL) 
//     {
//         printf("Can't malloc DMA memory!\n");
//         ak_vo_close(DEV_NUM);
//         fclose(fp);
//         return -1;
//     }

//     memset(_pic_obj->contentBuffer, 0, len);
//     if ( ( ret = fread(_pic_obj->contentBuffer, 1, len, fp) ) > 0 ) 
//     {     // read the file
//         printf("read [%d] byte to dma buffer\n",ret);
//     }
//     else
//     {
//         printf("read fail[%d]\n", ret);
//         ak_vo_close(DEV_NUM);
//         fclose(fp);
//         return -1;
//     }
    
//     fclose(fp);
//     return 0;
// }
